<html><!-- Created using the cpp_pretty_printer from the dlib C++ library.  See http://dlib.net for updates. --><head><title>dlib C++ Library - invoke.h</title></head><body bgcolor='white'><pre>
<font color='#009900'>// Copyright (C) 2021  Davis E. King (davis@dlib.net)
</font><font color='#009900'>// License: Boost Software License   See LICENSE.txt for the full license.
</font><font color='#0000FF'>#ifndef</font> DLIB_INVOKE_Hh_
<font color='#0000FF'>#define</font> DLIB_INVOKE_Hh_

<font color='#0000FF'>#include</font> <font color='#5555FF'>&lt;</font>functional<font color='#5555FF'>&gt;</font>
<font color='#0000FF'>#include</font> <font color='#5555FF'>&lt;</font>type_traits<font color='#5555FF'>&gt;</font>
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='utility.h.html'>utility.h</a>"

<font color='#0000FF'>namespace</font> dlib
<b>{</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>namespace</font> detail 
    <b>{</b>
        <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font> <font color='#0000FF'>typename</font> T <font color='#5555FF'>&gt;</font>
        <font color='#0000FF'>struct</font> <b><a name='is_reference_wrapper'></a>is_reference_wrapper</b> : std::false_type <b>{</b><b>}</b>;
        <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font> <font color='#0000FF'>typename</font> U <font color='#5555FF'>&gt;</font>
        <font color='#0000FF'>struct</font> <b><a name='is_reference_wrapper'></a>is_reference_wrapper</b><font color='#5555FF'>&lt;</font>std::reference_wrapper<font color='#5555FF'>&lt;</font>U<font color='#5555FF'>&gt;</font><font color='#5555FF'>&gt;</font> : std::true_type <b>{</b><b>}</b>;

        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> Base,
            <font color='#0000FF'>typename</font> T,
            <font color='#0000FF'>typename</font> Derived,
            <font color='#0000FF'>typename</font>... Args
        <font color='#5555FF'>&gt;</font>
        constexpr <font color='#0000FF'>auto</font> <b><a name='invoke_'></a>invoke_</b><font face='Lucida Console'>(</font>
            T Base::<font color='#5555FF'>*</font>pmf, <font color='#009900'>//pointer to member function
</font>            Derived<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> ref,
            Args<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>... args
        <font face='Lucida Console'>)</font>
        <b><a name='noexcept'></a>noexcept</b><font face='Lucida Console'>(</font><font color='#BB00BB'>noexcept</font><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Derived<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>ref<font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmf<font face='Lucida Console'>)</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>args<font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font> <font color='#0000FF'>typename</font> std::enable_if<font color='#5555FF'>&lt;</font>
                std::is_function<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font>::value <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>
                std::is_base_of<font color='#5555FF'>&lt;</font>Base, <font color='#0000FF'>typename</font> std::decay<font color='#5555FF'>&lt;</font>Derived<font color='#5555FF'>&gt;</font>::type<font color='#5555FF'>&gt;</font>::value,
                <b><a name='decltype'></a>decltype</b><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Derived<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>ref<font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmf<font face='Lucida Console'>)</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>args<font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
           <font color='#5555FF'>&gt;</font>::type
        <b>{</b>
            <font color='#0000FF'>return</font> <font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Derived<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>ref<font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmf<font face='Lucida Console'>)</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>args<font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> Base,
            <font color='#0000FF'>typename</font> T,
            <font color='#0000FF'>typename</font> RefWrap,
            <font color='#0000FF'>typename</font>... Args
        <font color='#5555FF'>&gt;</font>
        constexpr <font color='#0000FF'>auto</font> <b><a name='invoke_'></a>invoke_</b><font face='Lucida Console'>(</font>
            T Base::<font color='#5555FF'>*</font>pmf, <font color='#009900'>//pointer to member function
</font>            RefWrap<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> ref,
            Args<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>... args
        <font face='Lucida Console'>)</font>
        <b><a name='noexcept'></a>noexcept</b><font face='Lucida Console'>(</font><font color='#BB00BB'>noexcept</font><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>ref.<font color='#BB00BB'>get</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmf<font face='Lucida Console'>)</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>args<font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font> <font color='#0000FF'>typename</font> std::enable_if<font color='#5555FF'>&lt;</font>
                std::is_function<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font>::value <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>
                is_reference_wrapper<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> std::decay<font color='#5555FF'>&lt;</font>RefWrap<font color='#5555FF'>&gt;</font>::type<font color='#5555FF'>&gt;</font>::value,
                <b><a name='decltype'></a>decltype</b><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>ref.<font color='#BB00BB'>get</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmf<font face='Lucida Console'>)</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>args<font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font color='#5555FF'>&gt;</font>::type
        <b>{</b>
            <font color='#0000FF'>return</font> <font face='Lucida Console'>(</font>ref.<font color='#BB00BB'>get</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmf<font face='Lucida Console'>)</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>args<font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> Base,
            <font color='#0000FF'>typename</font> T,
            <font color='#0000FF'>typename</font> Ptr,
            <font color='#0000FF'>typename</font>... Args
        <font color='#5555FF'>&gt;</font>
        constexpr <font color='#0000FF'>auto</font> <b><a name='invoke_'></a>invoke_</b><font face='Lucida Console'>(</font>
            T Base::<font color='#5555FF'>*</font>pmf, <font color='#009900'>//pointer to member function
</font>            Ptr<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> ptr,
            Args<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>... args
        <font face='Lucida Console'>)</font>
        <b><a name='noexcept'></a>noexcept</b><font face='Lucida Console'>(</font><font color='#BB00BB'>noexcept</font><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font><font color='#5555FF'>*</font>std::forward<font color='#5555FF'>&lt;</font>Ptr<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>ptr<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmf<font face='Lucida Console'>)</font><font face='Lucida Console'>(</font> std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> args <font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font> <font color='#0000FF'>typename</font> std::enable_if<font color='#5555FF'>&lt;</font>
                std::is_function<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font>::value <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>
                <font color='#5555FF'>!</font>is_reference_wrapper<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> std::decay<font color='#5555FF'>&lt;</font>Ptr<font color='#5555FF'>&gt;</font>::type<font color='#5555FF'>&gt;</font>::value <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>
                <font color='#5555FF'>!</font>std::is_base_of<font color='#5555FF'>&lt;</font>Base, <font color='#0000FF'>typename</font> std::decay<font color='#5555FF'>&lt;</font>Ptr<font color='#5555FF'>&gt;</font>::type<font color='#5555FF'>&gt;</font>::value,
                <b><a name='decltype'></a>decltype</b><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font><font color='#5555FF'>*</font>std::forward<font color='#5555FF'>&lt;</font>Ptr<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>ptr<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmf<font face='Lucida Console'>)</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>args<font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font color='#5555FF'>&gt;</font>::type
        <b>{</b>
            <font color='#0000FF'>return</font> <font face='Lucida Console'>(</font><font face='Lucida Console'>(</font><font color='#5555FF'>*</font>std::forward<font color='#5555FF'>&lt;</font>Ptr<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>ptr<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmf<font face='Lucida Console'>)</font><font face='Lucida Console'>(</font> std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> args <font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> Base,
            <font color='#0000FF'>typename</font> T,
            <font color='#0000FF'>typename</font> Derived
        <font color='#5555FF'>&gt;</font>
        constexpr <font color='#0000FF'>auto</font> <b><a name='invoke_'></a>invoke_</b><font face='Lucida Console'>(</font>
            T Base::<font color='#5555FF'>*</font>pmd, <font color='#009900'>//pointer to member data
</font>            Derived<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> ref
        <font face='Lucida Console'>)</font>
        <b><a name='noexcept'></a>noexcept</b><font face='Lucida Console'>(</font><font color='#BB00BB'>noexcept</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Derived<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>ref<font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmd<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font> <font color='#0000FF'>typename</font> std::enable_if<font color='#5555FF'>&lt;</font>
                std::is_object<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font>::value <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>
                std::is_base_of<font color='#5555FF'>&lt;</font>Base, <font color='#0000FF'>typename</font> std::decay<font color='#5555FF'>&lt;</font>Derived<font color='#5555FF'>&gt;</font>::type<font color='#5555FF'>&gt;</font>::value,
                <b><a name='decltype'></a>decltype</b><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Derived<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>ref<font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmd<font face='Lucida Console'>)</font><font color='#5555FF'>&gt;</font>::type
        <b>{</b>
            <font color='#0000FF'>return</font> std::forward<font color='#5555FF'>&lt;</font>Derived<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>ref<font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmd;
        <b>}</b>

        <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> Base,
            <font color='#0000FF'>typename</font> T,
            <font color='#0000FF'>typename</font> RefWrap
        <font color='#5555FF'>&gt;</font>
        constexpr <font color='#0000FF'>auto</font> <b><a name='invoke_'></a>invoke_</b><font face='Lucida Console'>(</font>
            T Base::<font color='#5555FF'>*</font>pmd, <font color='#009900'>//pointer to member data
</font>            RefWrap<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> ref
        <font face='Lucida Console'>)</font>
        <b><a name='noexcept'></a>noexcept</b><font face='Lucida Console'>(</font><font color='#BB00BB'>noexcept</font><font face='Lucida Console'>(</font>ref.<font color='#BB00BB'>get</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmd<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font> <font color='#0000FF'>typename</font> std::enable_if<font color='#5555FF'>&lt;</font>
                std::is_object<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font>::value <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>
                is_reference_wrapper<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> std::decay<font color='#5555FF'>&lt;</font>RefWrap<font color='#5555FF'>&gt;</font>::type<font color='#5555FF'>&gt;</font>::value,
                <b><a name='decltype'></a>decltype</b><font face='Lucida Console'>(</font>ref.<font color='#BB00BB'>get</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmd<font face='Lucida Console'>)</font><font color='#5555FF'>&gt;</font>::type
        <b>{</b>
            <font color='#0000FF'>return</font> ref.<font color='#BB00BB'>get</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmd;
        <b>}</b>

        <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> Base,
            <font color='#0000FF'>typename</font> T,
            <font color='#0000FF'>typename</font> Ptr
        <font color='#5555FF'>&gt;</font>
        constexpr <font color='#0000FF'>auto</font> <b><a name='invoke_'></a>invoke_</b><font face='Lucida Console'>(</font>
            T Base::<font color='#5555FF'>*</font>pmd, <font color='#009900'>//pointer to member data
</font>            Ptr<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> ptr
        <font face='Lucida Console'>)</font>
        <b><a name='noexcept'></a>noexcept</b><font face='Lucida Console'>(</font><font color='#BB00BB'>noexcept</font><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font><font color='#5555FF'>*</font>std::forward<font color='#5555FF'>&lt;</font>Ptr<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>ptr<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmd<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font> <font color='#0000FF'>typename</font> std::enable_if<font color='#5555FF'>&lt;</font>
                std::is_object<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font>::value <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>
                <font color='#5555FF'>!</font>is_reference_wrapper<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> std::decay<font color='#5555FF'>&lt;</font>Ptr<font color='#5555FF'>&gt;</font>::type<font color='#5555FF'>&gt;</font>::value <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>
                <font color='#5555FF'>!</font>std::is_base_of<font color='#5555FF'>&lt;</font>Base, <font color='#0000FF'>typename</font> std::decay<font color='#5555FF'>&lt;</font>Ptr<font color='#5555FF'>&gt;</font>::type<font color='#5555FF'>&gt;</font>::value,
                <b><a name='decltype'></a>decltype</b><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font><font color='#5555FF'>*</font>std::forward<font color='#5555FF'>&lt;</font>Ptr<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>ptr<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmd<font face='Lucida Console'>)</font><font color='#5555FF'>&gt;</font>::type
        <b>{</b>
            <font color='#0000FF'>return</font> <font face='Lucida Console'>(</font><font color='#5555FF'>*</font>std::forward<font color='#5555FF'>&lt;</font>Ptr<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>ptr<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>.<font color='#5555FF'>*</font>pmd;
        <b>}</b>

        <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> F,
            <font color='#0000FF'>typename</font>... Args
        <font color='#5555FF'>&gt;</font>
        constexpr <font color='#0000FF'>auto</font> <b><a name='invoke_'></a>invoke_</b><font face='Lucida Console'>(</font>
            F <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> f,
            Args<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>... args
        <font face='Lucida Console'>)</font>
        <b><a name='noexcept'></a>noexcept</b><font face='Lucida Console'>(</font><font color='#BB00BB'>noexcept</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> f <font face='Lucida Console'>)</font><font face='Lucida Console'>(</font> std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> args <font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font> <font color='#0000FF'>typename</font> std::enable_if<font color='#5555FF'>&lt;</font>
                <font color='#5555FF'>!</font>std::is_member_pointer<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> std::decay<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font>::type<font color='#5555FF'>&gt;</font>::value,
                <b><a name='decltype'></a>decltype</b><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>f<font face='Lucida Console'>)</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>args<font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font color='#5555FF'>&gt;</font>::type
        <b>{</b>
            <font color='#0000FF'>return</font> std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> f <font face='Lucida Console'>)</font><font face='Lucida Console'>(</font> std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> args <font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font>;
        <b>}</b>
    <b>}</b> <font color='#009900'>// end namespace detail
</font>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>    
    <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font> <font color='#0000FF'>typename</font> F, <font color='#0000FF'>typename</font>... Args<font color='#5555FF'>&gt;</font>
    constexpr <font color='#0000FF'>auto</font> <b><a name='invoke'></a>invoke</b><font face='Lucida Console'>(</font>F <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> f, Args <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>... args<font face='Lucida Console'>)</font>
    <font color='#009900'>/*!
        ensures
            - identical to std::invoke(std::forward&lt;F&gt;(f), std::forward&lt;Args&gt;(args)...)
            - works with C++11 onwards
    !*/</font>
    <b><a name='noexcept'></a>noexcept</b><font face='Lucida Console'>(</font><font color='#BB00BB'>noexcept</font><font face='Lucida Console'>(</font>detail::<font color='#BB00BB'>invoke_</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> f <font face='Lucida Console'>)</font>, std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> args <font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
    <font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font> <b><a name='decltype'></a>decltype</b><font face='Lucida Console'>(</font>detail::<font color='#BB00BB'>invoke_</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> f <font face='Lucida Console'>)</font>, std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> args <font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'>return</font> detail::<font color='#BB00BB'>invoke_</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> f <font face='Lucida Console'>)</font>, std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> args <font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>namespace</font> detail
    <b>{</b>
        <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font> <font color='#0000FF'>typename</font> AlwaysVoid, <font color='#0000FF'>typename</font>, <font color='#0000FF'>typename</font>...<font color='#5555FF'>&gt;</font>
        <font color='#0000FF'>struct</font> <b><a name='invoke_traits'></a>invoke_traits</b>
        <b>{</b>
            <font color='#0000FF'>static</font> constexpr <font color='#0000FF'><u>bool</u></font> value <font color='#5555FF'>=</font> <font color='#979000'>false</font>;
        <b>}</b>;

        <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font> <font color='#0000FF'>typename</font> F, <font color='#0000FF'>typename</font>... Args <font color='#5555FF'>&gt;</font>
        <font color='#0000FF'>struct</font> <b><a name='invoke_traits'></a>invoke_traits</b><font color='#5555FF'>&lt;</font> <b><a name='decltype'></a>decltype</b><font face='Lucida Console'>(</font> <font color='#0000FF'><u>void</u></font><font face='Lucida Console'>(</font>dlib::<font color='#BB00BB'>invoke</font><font face='Lucida Console'>(</font>std::declval<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, std::declval<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font face='Lucida Console'>)</font>, F, Args...<font color='#5555FF'>&gt;</font>
        <b>{</b>
            <font color='#0000FF'>static</font> constexpr <font color='#0000FF'><u>bool</u></font> value <font color='#5555FF'>=</font> <font color='#979000'>true</font>;
            <font color='#0000FF'>using</font> type <font color='#5555FF'>=</font> <font color='#BB00BB'>decltype</font><font face='Lucida Console'>(</font> dlib::<font color='#BB00BB'>invoke</font><font face='Lucida Console'>(</font>std::declval<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, std::declval<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font> <font face='Lucida Console'>)</font>;
        <b>}</b>;
    <b>}</b> <font color='#009900'>// end namespace detail
</font>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font> <font color='#0000FF'>typename</font> F, <font color='#0000FF'>typename</font>... Args <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='invoke_result'></a>invoke_result</b> : detail::invoke_traits<font color='#5555FF'>&lt;</font> <font color='#0000FF'><u>void</u></font>, F, Args...<font color='#5555FF'>&gt;</font> <b>{</b><b>}</b>;
    <font color='#009900'>/*!
        ensures
            - identical to std::invoke_result&lt;F, Args..&gt;
            - works with C++11 onwards
    !*/</font>

    <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font> <font color='#0000FF'>typename</font> F, <font color='#0000FF'>typename</font>... Args <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>using</font> invoke_result_t <font color='#5555FF'>=</font> <font color='#0000FF'>typename</font> invoke_result<font color='#5555FF'>&lt;</font>F, Args...<font color='#5555FF'>&gt;</font>::type;
    <font color='#009900'>/*!
        ensures
            - identical to std::invoke_result_t&lt;F, Args..&gt;
            - works with C++11 onwards
    !*/</font>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font> <font color='#0000FF'>typename</font> F, <font color='#0000FF'>typename</font>... Args <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='is_invocable'></a>is_invocable</b> : std::integral_constant<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>bool</u></font>, detail::invoke_traits<font color='#5555FF'>&lt;</font> <font color='#0000FF'><u>void</u></font>, F, Args...<font color='#5555FF'>&gt;</font>::value<font color='#5555FF'>&gt;</font> <b>{</b><b>}</b>;
    <font color='#009900'>/*!
        ensures
            - identical to std::is_invocable&lt;F, Args..&gt;
            - works with C++11 onwards
    !*/</font>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> R, <font color='#0000FF'>typename</font> F, <font color='#0000FF'>typename</font>... Args<font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='is_invocable_r'></a>is_invocable_r</b> : std::integral_constant<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>bool</u></font>, dlib::is_invocable<font color='#5555FF'>&lt;</font>F, Args...<font color='#5555FF'>&gt;</font>::value <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>
                                                         std::is_convertible<font color='#5555FF'>&lt;</font>invoke_result_t<font color='#5555FF'>&lt;</font>F, Args...<font color='#5555FF'>&gt;</font>, R<font color='#5555FF'>&gt;</font>::value<font color='#5555FF'>&gt;</font> <b>{</b><b>}</b>;
    <font color='#009900'>/*!
        ensures
            - identical to std::is_invocable_r&lt;R, F, Args..&gt;
            - works with C++11 onwards
    !*/</font>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font> <font color='#0000FF'>typename</font> R, <font color='#0000FF'>typename</font> F, <font color='#0000FF'>typename</font>... Args<font color='#5555FF'>&gt;</font>
    constexpr <font color='#0000FF'>typename</font> std::enable_if<font color='#5555FF'>&lt;</font>dlib::is_invocable_r<font color='#5555FF'>&lt;</font>R, F, Args...<font color='#5555FF'>&gt;</font>::value, R<font color='#5555FF'>&gt;</font>::type
    <b><a name='invoke_r'></a>invoke_r</b><font face='Lucida Console'>(</font>F <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> f, Args <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font>... args<font face='Lucida Console'>)</font>
    <font color='#009900'>/*!
        ensures
            - identical to std::invoke_r&lt;R&gt;(std::forward&lt;F&gt;(f), std::forward&lt;Args&gt;(args)...)
            - works with C++11 onwards
    !*/</font>
    <b><a name='noexcept'></a>noexcept</b><font face='Lucida Console'>(</font><font color='#BB00BB'>noexcept</font><font face='Lucida Console'>(</font>dlib::<font color='#BB00BB'>invoke</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> f <font face='Lucida Console'>)</font>, std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> args <font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'>return</font> dlib::<font color='#BB00BB'>invoke</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> f <font face='Lucida Console'>)</font>, std::forward<font color='#5555FF'>&lt;</font>Args<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font> args <font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>namespace</font> detail
    <b>{</b>
        <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> F, <font color='#0000FF'>typename</font> Tuple, std::<font color='#0000FF'><u>size_t</u></font>... I<font color='#5555FF'>&gt;</font>
        constexpr <font color='#0000FF'>auto</font> <b><a name='apply_impl'></a>apply_impl</b><font face='Lucida Console'>(</font>F<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> fn, Tuple<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> tpl, index_sequence<font color='#5555FF'>&lt;</font>I...<font color='#5555FF'>&gt;</font><font face='Lucida Console'>)</font>
        <b><a name='noexcept'></a>noexcept</b><font face='Lucida Console'>(</font><font color='#BB00BB'>noexcept</font><font face='Lucida Console'>(</font>dlib::<font color='#BB00BB'>invoke</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>fn<font face='Lucida Console'>)</font>,
                                       std::get<font color='#5555FF'>&lt;</font>I<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Tuple<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>tpl<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font> <b><a name='decltype'></a>decltype</b><font face='Lucida Console'>(</font>dlib::<font color='#BB00BB'>invoke</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>fn<font face='Lucida Console'>)</font>,
                                 std::get<font color='#5555FF'>&lt;</font>I<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Tuple<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>tpl<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>return</font> dlib::<font color='#BB00BB'>invoke</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>fn<font face='Lucida Console'>)</font>,
                                std::get<font color='#5555FF'>&lt;</font>I<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Tuple<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>tpl<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font>;
        <b>}</b>
    <b>}</b> <font color='#009900'>// end namespace detail
</font>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font><font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> F, <font color='#0000FF'>typename</font> Tuple<font color='#5555FF'>&gt;</font>
    constexpr <font color='#0000FF'>auto</font> <b><a name='apply'></a>apply</b><font face='Lucida Console'>(</font>F<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> fn, Tuple<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> tpl<font face='Lucida Console'>)</font>
    <font color='#009900'>/*!
        ensures
            - identical to std::apply(std::forward&lt;F&gt;(f), std::forward&lt;Tuple&gt;(tpl))
            - works with C++11 onwards
    !*/</font>
    <b><a name='noexcept'></a>noexcept</b><font face='Lucida Console'>(</font><font color='#BB00BB'>noexcept</font><font face='Lucida Console'>(</font>detail::<font color='#BB00BB'>apply_impl</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>fn<font face='Lucida Console'>)</font>,
                                         std::forward<font color='#5555FF'>&lt;</font>Tuple<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>tpl<font face='Lucida Console'>)</font>,
                                         make_index_sequence<font color='#5555FF'>&lt;</font>std::tuple_size<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> std::remove_reference<font color='#5555FF'>&lt;</font>Tuple<font color='#5555FF'>&gt;</font>::type <font color='#5555FF'>&gt;</font>::value<font color='#5555FF'>&gt;</font><b>{</b><b>}</b><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
    <font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font> <b><a name='decltype'></a>decltype</b><font face='Lucida Console'>(</font>detail::<font color='#BB00BB'>apply_impl</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>fn<font face='Lucida Console'>)</font>,
                                   std::forward<font color='#5555FF'>&lt;</font>Tuple<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>tpl<font face='Lucida Console'>)</font>,
                                   make_index_sequence<font color='#5555FF'>&lt;</font>std::tuple_size<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> std::remove_reference<font color='#5555FF'>&lt;</font>Tuple<font color='#5555FF'>&gt;</font>::type <font color='#5555FF'>&gt;</font>::value<font color='#5555FF'>&gt;</font><b>{</b><b>}</b><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'>return</font> detail::<font color='#BB00BB'>apply_impl</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>F<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>fn<font face='Lucida Console'>)</font>,
                                  std::forward<font color='#5555FF'>&lt;</font>Tuple<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>tpl<font face='Lucida Console'>)</font>,
                                  make_index_sequence<font color='#5555FF'>&lt;</font>std::tuple_size<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> std::remove_reference<font color='#5555FF'>&lt;</font>Tuple<font color='#5555FF'>&gt;</font>::type <font color='#5555FF'>&gt;</font>::value<font color='#5555FF'>&gt;</font><b>{</b><b>}</b><font face='Lucida Console'>)</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>namespace</font> detail
    <b>{</b>
        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>class</font> <b><a name='T'></a>T</b>, <font color='#0000FF'>class</font> <b><a name='Tuple'></a>Tuple</b>, std::<font color='#0000FF'><u>size_t</u></font>... I<font color='#5555FF'>&gt;</font>
        constexpr T <b><a name='make_from_tuple_impl'></a>make_from_tuple_impl</b><font face='Lucida Console'>(</font> Tuple<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> t, index_sequence<font color='#5555FF'>&lt;</font>I...<font color='#5555FF'>&gt;</font> <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>return</font> <font color='#BB00BB'>T</font><font face='Lucida Console'>(</font>std::get<font color='#5555FF'>&lt;</font>I<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Tuple<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>t<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>...<font face='Lucida Console'>)</font>;
        <b>}</b>
    <b>}</b> <font color='#009900'>// end namespace detail
</font>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>class</font> <b><a name='T'></a>T</b>, <font color='#0000FF'>class</font> <b><a name='Tuple'></a>Tuple</b><font color='#5555FF'>&gt;</font>
    constexpr T <b><a name='make_from_tuple'></a>make_from_tuple</b><font face='Lucida Console'>(</font> Tuple<font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> t <font face='Lucida Console'>)</font>
    <font color='#009900'>/*!
        ensures
            - identical to std::make_from_tuple&lt;T&gt;(std::forward&lt;Tuple&gt;(t))
            - works with C++11 onwards
    !*/</font>
    <b>{</b>
        <font color='#0000FF'>return</font> detail::make_from_tuple_impl<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>std::forward<font color='#5555FF'>&lt;</font>Tuple<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>t<font face='Lucida Console'>)</font>,
                                               make_index_sequence<font color='#5555FF'>&lt;</font>std::tuple_size<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> std::remove_reference<font color='#5555FF'>&lt;</font>Tuple<font color='#5555FF'>&gt;</font>::type <font color='#5555FF'>&gt;</font>::value<font color='#5555FF'>&gt;</font><b>{</b><b>}</b><font face='Lucida Console'>)</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
<b>}</b>

<font color='#0000FF'>#endif</font> <font color='#009900'>//DLIB_INVOKE_Hh_
</font>
</pre></body></html>